package com.persistence;

import com.models.Column;
import com.util.Constants;
import com.util.Error;
import com.file.FileManager;
import com.models.Table;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.util.ArrayList;

/**
 * Created by TimeLiar on 2015/9/22.
 *
 */
public enum TablePersistence {
    @SuppressWarnings("unused")
    INSTANCE;
    private static final ArrayList<Table> tableSet = new ArrayList<>();

    static {
        try {
            initSet();
        } catch (Error error) {
            System.out.println(error.getMessage());
            System.exit(0);
        }
    }

    //创建新表
    public static void createTable(Table table) throws Error {
        if (table == null || table.getName() == null) {
            throw new Error("null error");
        }
        for (Table table1 : tableSet) {
            if (table.getName().equals(table1.getName())) {
                throw new Error(table.getName() + " is exist");
            }
        }
        try {
            FileManager.writeFile(table, Constants.TABLE_STRUCTURE.replace("*",table.getName()), false);
            synchronized (tableSet) {
                tableSet.add(table);
            }
        } catch (Exception e) {
            File file = new File(Constants.TABLE_STRUCTURE.replace("*",table.getName()));
            if (file.exists() && file.isFile()) {
                if (!file.delete()) {
                    System.out.println("delete error");
                }
                throw new Error(e.getMessage());
            }
        }
    }

    //初始化表结构集合
    public static void initSet() throws Error {
        synchronized (tableSet) {
            tableSet.clear();
            File directory = new File(Constants.TABLE_HOME);
            String[] names = directory.list();
            if(names != null){
                for (String name : names) {
                    if(name.endsWith(".def")){
                        name = name.substring(0,name.indexOf("."));
                        Table table = new Table();
                        table.setName(name);
                        table.setColumns(new ArrayList<>());
                        String jsonString;
                        try {
                            jsonString = FileManager.readFile(Constants.TABLE_STRUCTURE.replace("*",name));
                            if (jsonString == null || (!jsonString.startsWith("[") && !jsonString.endsWith("]"))) {
                                FileManager.writeFile("[]", Constants.TABLE_STRUCTURE.replace("*",name), false);
                            }
                        } catch (Exception e) {
                            throw new Error(e.getMessage());
                        }
                        try {
                            JSONArray jsonArray = new JSONArray(jsonString);
                            for (int i = 0; i < jsonArray.length(); i++) {
                                JSONObject jsonObject = jsonArray.getJSONObject(i);
                                Column column = new Column(
                                        jsonObject.getString("name"),
                                        jsonObject.getString("type"),
                                        jsonObject.getInt("length"),
                                        jsonObject.getBoolean("pk"),
                                        jsonObject.getBoolean("nn")
                                );
                                table.getColumns().add(column);
                            }
                            tableSet.add(table);
                        } catch (JSONException e) {
                            System.err.println(e.getMessage());
                            System.exit(0);
                        }
                    }
                }
            }
        }
    }

    public static boolean removeTable(String tableName) {
        synchronized (tableSet) {
            File file = new File(Constants.TABLE_STRUCTURE.replace("*",tableName));
            Table table = getTable(tableName);
            return file.delete() && tableSet.remove(table);
        }
    }

    public static Table getTable(String name) {
        for (Table table : tableSet) {
            if (table.getName() != null && table.getName().equals(name)) {
                return table;
            }
        }
        return null;
    }

    public static void updateTable(Table table) throws Error {
        if (table == null || table.getName() == null) {
            throw new Error("null error");
        }
        try {
            FileManager.writeFile(table, Constants.TABLE_STRUCTURE.replace("*",table.getName()), false);
        } catch (Exception e) {
            throw new Error(e.getMessage());
        }
        synchronized (tableSet) {
            tableSet.remove(table);
            tableSet.add(table);
        }
    }

    public static ArrayList<Table> allTables(){
        return tableSet;
    }
}
